﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.Revit.RevitExtension;
using YJKControls.Previewer;
using YJKDragCurveJig;

namespace YJKArch.ElevationDim
{
	public partial class DlgElevationDim : System.Windows.Forms.Form
	{
		public bool InfoChanged
		{
			get
			{
				return this.m_InfoChanged;
			}
			set
			{
				if (this.m_IsInitialize)
				{
					this.m_InfoChanged = value;
				}
			}
		}

		public DlgElevationDim(ExternalCommandData ecd)
		{
			this.m_IsInitialize = false;
			this.InitializeComponent();
			this.m_Previewer = new Previewer(1u);
			base.Controls.Add(this.m_Previewer);
			this.m_Previewer.Location = new System.Drawing.Point(this.label3.Left, this.lbxElevation.Top);
			this.m_Previewer.Size = new Size(this.txtNum.Right - this.label3.Left, this.rbRight.Bottom - this.lbxElevation.Top);
			this.m_Previewer.TabIndex = 7;
			this.m_Previewer.TabStop = false;
			this.Revit = ecd;
			this.RefreshLevels();
			this.RefreshType();
			this.Levels = new List<ShowLevel>();
			this.showLevels();
			this.m_IsInitialize = true;
		}

		public void RefreshLevels()
		{
			this.lbxElevation.Items.Clear();
			List<Level> allLevel = AssistFunc.GetAllLevel(this.Revit.Application.ActiveUIDocument.Document);
			this.Sort(allLevel);
			foreach (Level level in allLevel)
			{
				ShowLevel item = new ShowLevel(level);
				this.lbxElevation.Items.Add(item, true);
			}
			this.InfoChanged = true;
		}

		private void RefreshType()
		{
			this.cbxStyle.Items.Clear();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.Revit.Application.ActiveUIDocument.Document);
			filteredElementCollector.OfClass(typeof(TextNoteType));
			if (filteredElementCollector != null)
			{
				IEnumerable<Element> enumerable = filteredElementCollector.ToElements();
				new List<Element>();
				foreach (Element element in enumerable)
				{
					this.cbxStyle.Items.Add(new ShowType(element as TextNoteType));
				}
			}
			if (this.cbxStyle.Items.Count > 0)
			{
				this.cbxStyle.SelectedIndex = 0;
			}
			this.textNoteType = ((ShowType)this.cbxStyle.SelectedItem).Type;
		}

		private int GetStrCaculateLength(string str)
		{
			if (str.Length == 0)
			{
				return 0;
			}
			Encoding encoding = new ASCIIEncoding();
			int num = 0;
			byte[] bytes = encoding.GetBytes(str);
			for (int i = 0; i < bytes.Length; i++)
			{
				if (bytes[i] == 63)
				{
					num += 2;
				}
				else
				{
					num++;
				}
			}
			return num;
		}

		public bool CreateJigData(Autodesk.Revit.DB.View view, ref XYZ ptBase, ref List<JigEdgeInfo> curveInfoList, ref List<JigTextInfo> textInfoList)
		{
			ptBase = XYZ.Zero;
			curveInfoList = new List<JigEdgeInfo>();
			textInfoList = new List<JigTextInfo>();
			TextNoteType textNoteType = this.textNoteType;
			TextNoteType textNoteType2 = textNoteType as TextNoteType;
			double num = textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble() * (double)view.Scale;
			double num2 = textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			XYZ baseVec = new XYZ(1.0, 0.0, 0.0);
			XYZ upVec = new XYZ(0.0, 0.0, 1.0);
			if (this.Levels.Count <= 0)
			{
				JigTextInfo item = new JigTextInfo(textNoteType2, XYZ.Zero, baseVec, upVec, (Autodesk.Revit.DB.TextAlignFlags)2112, 0.001, "   ");
				textInfoList.Add(item);
			}
			else
			{
				textInfoList.Clear();
			}
			int num3 = 0;
			int num4 = 0;
			foreach (ShowLevel showLevel in this.Levels)
			{
				if (showLevel.NumLength > num3)
				{
					num3 = showLevel.NumLength;
				}
				if (showLevel.StrLength > num4)
				{
					num4 = showLevel.StrLength;
				}
			}
			double num5 = num * num2;
			num5 *= 0.66666666666666663;
			double num6 = 0.0;
			foreach (ShowLevel showLevel2 in this.Levels)
			{
				string valueString = showLevel2.GetValueString(num3, true);
				double num7 = (double)this.GetStrCaculateLength(valueString) * num5;
				if (num7 > num6)
				{
					num6 = num7;
				}
			}
			double num8 = num * 2.0 * this.GetTextHScale(textNoteType2.Name);
			double num9 = AssistFunc.mmToFeet(3.5) * (double)view.Scale;
			for (int i = 0; i < this.Levels.Count; i++)
			{
				ShowLevel showLevel3 = this.Levels[i];
				string valueString2;
				if (this.rbLeft.Checked)
				{
					valueString2 = showLevel3.GetValueString(num3, true);
				}
				else
				{
					valueString2 = showLevel3.GetValueString(num4, false);
				}
				double num10;
				if (this.rbLeft.Checked)
				{
					if (this.chbAutoReturn.Checked)
					{
						num10 = (AssistFunc.IsOdd(i) ? num6 : 0.0);
					}
					else
					{
						num10 = 0.0;
					}
				}
				else
				{
					if (this.chbAutoReturn.Checked)
					{
						num10 = (AssistFunc.IsOdd(i) ? (-2.0 * num6) : (-num6));
					}
					else
					{
						num10 = -num6;
					}
					num10 += num9 / 2.0;
				}
				XYZ origin = new XYZ(num10, num8, 0.0);
				JigTextInfo item2 = new JigTextInfo(textNoteType2, origin, baseVec, upVec, (Autodesk.Revit.DB.TextAlignFlags)576, num6 * 1.5, valueString2);
				textInfoList.Add(item2);
				if (this.chbAutoReturn.Checked)
				{
					num8 = (AssistFunc.IsOdd(i) ? (num8 + num * 1.3) : num8);
				}
				else
				{
					num8 += num * 1.3;
				}
			}
			if (this.Levels.Count > 0)
			{
				if (this.rbLeft.Checked)
				{
					double num11 = num6;
					if (this.chbAutoReturn.Checked && this.Levels.Count > 1)
					{
						num11 = num6 * 2.0;
					}
					XYZ xyz = new XYZ(ptBase.X - num9 / 2.0, ptBase.Y + num9 / 2.0, ptBase.Z);
					XYZ endPoint = new XYZ(xyz.X + num11, xyz.Y, ptBase.Z);
					XYZ startPoint = new XYZ(xyz.X + num9, xyz.Y, ptBase.Z);
					JigEdgeInfo item3 = new JigEdgeInfo(xyz, endPoint, 0.0);
					JigEdgeInfo item4 = new JigEdgeInfo(xyz, ptBase, 0.0);
					JigEdgeInfo item5 = new JigEdgeInfo(startPoint, ptBase, 0.0);
					curveInfoList.Add(item3);
					curveInfoList.Add(item4);
					curveInfoList.Add(item5);
				}
				else
				{
					double num12 = num6;
					if (this.chbAutoReturn.Checked && this.Levels.Count > 1)
					{
						num12 = num6 * 2.0;
					}
					XYZ xyz2 = new XYZ(ptBase.X + num9 / 2.0, ptBase.Y + num9 / 2.0, ptBase.Z);
					XYZ endPoint2 = new XYZ(xyz2.X - num12, xyz2.Y, ptBase.Z);
					XYZ startPoint2 = new XYZ(xyz2.X - num9, xyz2.Y, ptBase.Z);
					JigEdgeInfo item6 = new JigEdgeInfo(xyz2, endPoint2, 0.0);
					JigEdgeInfo item7 = new JigEdgeInfo(xyz2, ptBase, 0.0);
					JigEdgeInfo item8 = new JigEdgeInfo(startPoint2, ptBase, 0.0);
					curveInfoList.Add(item6);
					curveInfoList.Add(item7);
					curveInfoList.Add(item8);
				}
			}
			return true;
		}

		public double GetTextHScale(string sTextStyle)
		{
			if (sTextStyle.Contains("HY_Arial"))
			{
				return 1.3;
			}
			return 1.0;
		}

		private int GetLength(string str)
		{
			if (str.Length == 0)
			{
				return 0;
			}
			Encoding encoding = new ASCIIEncoding();
			int num = 0;
			byte[] bytes = encoding.GetBytes(str);
			for (int i = 0; i < bytes.Length; i++)
			{
				if (bytes[i] == 63)
				{
					num += 2;
				}
				else
				{
					num++;
				}
			}
			return num;
		}

		private void RefreshPreview()
		{
			if (this.Levels.Count < 1)
			{
				return;
			}
			List<TextNoteInfo> list = new List<TextNoteInfo>();
			List<CurveInfo> list2 = new List<CurveInfo>();
			double num = 0.0;
			double num2 = 0.0;
			try
			{
				int num3 = 0;
				int num4 = 0;
				foreach (ShowLevel showLevel in this.Levels)
				{
					if (showLevel.NumLength > num3)
					{
						num3 = showLevel.NumLength;
					}
					if (showLevel.StrLength > num4)
					{
						num4 = showLevel.StrLength;
					}
				}
				foreach (ShowLevel showLevel2 in this.Levels)
				{
					string valueString = showLevel2.GetValueString(num3, true);
					double num5 = 7.5 * (double)this.GetLength(valueString);
					if (num5 > num)
					{
						num = num5;
					}
				}
				for (int i = 0; i < this.Levels.Count; i++)
				{
					ShowLevel showLevel3 = this.Levels[i];
					string text = this.rbLeft.Checked ? showLevel3.GetValueString(num3, true) : showLevel3.GetValueString(num4, false);
					double num6;
					if (this.chbAutoReturn.Checked)
					{
						num6 = (AssistFunc.IsOdd(i) ? num : 0.0);
					}
					else
					{
						num6 = 0.0;
					}
					TextNoteInfo item = new TextNoteInfo(text, PenColor.PC_Green, 10.0, new XYZ(num6, num2, 0.0), TextNoteInfo.AlignHType.AHT_Left, TextNoteInfo.AlignVType.AVT_Bottom, 7.5 * (double)this.GetLength(text), 15.0);
					list.Add(item);
					if (this.chbAutoReturn.Checked)
					{
						num2 = ((!AssistFunc.IsOdd(i)) ? num2 : (num2 + 18.0));
					}
					else
					{
						num2 += 18.0;
					}
				}
				num2 = -10.0;
				if (this.rbLeft.Checked)
				{
					if (this.chbAutoReturn.Checked && this.Levels.Count > 1)
					{
						num *= 2.0;
					}
					Line curve = YJKLineEx.YJKGetBound(new XYZ(num, num2, 0.0), new XYZ(0.0, num2, 0.0));
					XYZ endPoint = new XYZ(0.0, num2, 0.0);
					XYZ endPoint2 = new XYZ(12.0, num2, 0.0);
					XYZ startPoint = new XYZ(6.0, num2 - 6.0, 0.0);
					Line curve2 = YJKLineEx.YJKGetBound(startPoint, endPoint);
					Line curve3 = YJKLineEx.YJKGetBound(startPoint, endPoint2);
					CurveInfo item2 = new CurveInfo(curve, PenColor.PC_Green, 1f);
					CurveInfo item3 = new CurveInfo(curve2, PenColor.PC_Green, 1f);
					CurveInfo item4 = new CurveInfo(curve3, PenColor.PC_Green, 1f);
					list2.Add(item2);
					list2.Add(item3);
					list2.Add(item4);
				}
				else
				{
					if (this.chbAutoReturn.Checked && this.Levels.Count > 1)
					{
						num *= 2.0;
					}
					Line curve4 = YJKLineEx.YJKGetBound(new XYZ(0.0, num2, 0.0), new XYZ(num, num2, 0.0));
					XYZ endPoint3 = new XYZ(num, num2, 0.0);
					XYZ endPoint4 = new XYZ(num - 12.0, num2, 0.0);
					XYZ startPoint2 = new XYZ(num - 6.0, num2 - 6.0, 0.0);
					Line curve5 = YJKLineEx.YJKGetBound(startPoint2, endPoint3);
					Line curve6 = YJKLineEx.YJKGetBound(startPoint2, endPoint4);
					CurveInfo item5 = new CurveInfo(curve4, PenColor.PC_Green, 1f);
					CurveInfo item6 = new CurveInfo(curve5, PenColor.PC_Green, 1f);
					CurveInfo item7 = new CurveInfo(curve6, PenColor.PC_Green, 1f);
					list2.Add(item5);
					list2.Add(item6);
					list2.Add(item7);
				}
			}
			catch
			{
			}
			this.m_Previewer.TextNotes = list;
			this.m_Previewer.Curves = list2;
			this.m_Previewer.ZoomExtents();
		}

		private void lbxElevation_MouseClick(object sender, MouseEventArgs e)
		{
			if (this.lbxElevation.SelectedItem != null)
			{
				if (((ListBox)sender).IndexFromPoint(e.X, e.Y) == -1)
				{
					this.lbxElevation.ClearSelected();
				}
				base.OnMouseDoubleClick(e);
				this.InfoChanged = true;
				this.showLevels();
			}
		}

		private void lbxElevation_MouseDoubleClick(object sender, MouseEventArgs e)
		{
			if (this.lbxElevation.SelectedItem != null)
			{
				if (((ListBox)sender).IndexFromPoint(e.X, e.Y) == -1)
				{
					this.lbxElevation.ClearSelected();
				}
				this.InfoChanged = true;
				this.showLevels();
			}
		}

		private void lbxElevation_SelectedIndexChanged(object sender, EventArgs e)
		{
			this.InfoChanged = true;
			this.showLevels();
		}

		private void showLevels()
		{
			this.getLevels();
			this.RefreshPreview();
		}

		private void getLevels()
		{
			this.Levels.Clear();
			for (int i = 0; i < this.lbxElevation.CheckedItems.Count; i++)
			{
				ShowLevel item = (ShowLevel)this.lbxElevation.CheckedItems[i];
				this.Levels.Add(item);
			}
			this.Sort(this.Levels);
		}

		private void Sort(List<ShowLevel> levels)
		{
			for (int i = 0; i < levels.Count - 1; i++)
			{
				for (int j = 0; j < levels.Count - 1; j++)
				{
					if (levels[j].Level.Elevation > levels[j + 1].Level.Elevation)
					{
						ShowLevel value = levels[j];
						levels[j] = levels[j + 1];
						levels[j + 1] = value;
					}
				}
			}
		}

		private void Sort(List<Level> levels)
		{
			for (int i = 0; i < levels.Count - 1; i++)
			{
				for (int j = 0; j < levels.Count - 1; j++)
				{
					if (levels[j].Elevation > levels[j + 1].Elevation)
					{
						Level value = levels[j];
						levels[j] = levels[j + 1];
						levels[j + 1] = value;
					}
				}
			}
		}

		[DllImport("user32.dll")]
		public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		private void SendESC()
		{
			int bVk = 27;
			int dwFlags = 0;
			int dwFlags2 = 2;
			int wMsg = 7;
			DlgElevationDim.SendMessage(CmdElevationDim.wndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			DlgElevationDim.keybd_event((byte)bVk, 0, dwFlags, 0);
			DlgElevationDim.keybd_event((byte)bVk, 0, dwFlags2, 0);
		}

		private void DlgElevationDim_Load(object sender, EventArgs e)
		{
		}

		private void cbxStyle_SelectedIndexChanged(object sender, EventArgs e)
		{
			this.textNoteType = (this.cbxStyle.SelectedItem as ShowType).Type;
			this.InfoChanged = true;
		}

		private void radioButton1_CheckedChanged(object sender, EventArgs e)
		{
			this.InfoChanged = true;
			this.RefreshPreview();
		}

		private void radioButton2_CheckedChanged(object sender, EventArgs e)
		{
			this.InfoChanged = true;
			this.RefreshPreview();
		}

		private void DlgElevationDim_MouseLeave(object sender, EventArgs e)
		{
			this.turnToRevit();
		}

		private void turnToRevit()
		{
			if (!base.ClientRectangle.Contains(base.PointToClient(Cursor.Position)))
			{
				int wMsg = 7;
				DlgElevationDim.SendMessage(CmdElevationDim.wndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
				if (this.InfoChanged)
				{
					this.SendESC();
					return;
				}
			}
			else
			{
				base.Focus();
			}
		}

		private void txtNum_TextChanged(object sender, EventArgs e)
		{
			if (this.txtNum.Text == "")
			{
				this.txtNum.Text = "0";
			}
			this.getLevels();
			this.m_InfoChanged = true;
			this.RefreshPreview();
		}

		private void DlgElevationDim_FormClosing(object sender, FormClosingEventArgs e)
		{
			this.SendESC();
		}

		private void lbxElevation_Click(object sender, EventArgs e)
		{
			this.showLevels();
		}

		private void lbxElevation_DoubleClick(object sender, EventArgs e)
		{
			this.showLevels();
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			base.Close();
		}

		private void chbAutoReturn_CheckedChanged(object sender, EventArgs e)
		{
			this.m_InfoChanged = true;
			this.RefreshPreview();
		}

		public ExternalCommandData Revit;

		public List<ShowLevel> Levels = new List<ShowLevel>();

		private TextNoteType textNoteType;

		private bool m_InfoChanged;

		private bool m_IsInitialize;

		private Previewer m_Previewer;
	}
}
